package com.wave.traffic.modbus;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * modbus工具类
 * 林晖
 */
public class ModbusUtil {

    private final static Logger logger = LoggerFactory.getLogger(ModbusUtil.class);


    public static Socket getClient(String ip,int port){
        logger.info("尝试连接");
        Socket s = null;
        try {
            s = new Socket(ip, port);
        } catch (IOException e) {
            logger.error("getClient throws exception is {}", e.getMessage(),e);
        }catch (Exception e){
            logger.error("getClient throws exception is {}", e.getMessage(),e);
        }
        return s;
    }

    public static String getData(Socket s,String instruct) throws IOException {
        InputStream is = s.getInputStream();
        BufferedInputStream bis = new BufferedInputStream( is );
        byte[] bytes = new byte[10]; // 一次读取一个byte
        String ret = "";
        bis.read(bytes);
        ret += bytesToHexString(bytes) + " ";  //调用字节转化16进制字符串方法


        logger.info("服务器：{}",ret);
        return ret;
    }


    /**
     * 给指定的网络控制器发送指令
     * @param s 客户端
     * @param instruct 指令
     * @return ret 执行结果
     */
    public static String sendInstruct(Socket s,String instruct) throws IOException {
        try {
            logger.info("连接成功！");
            //构建IO
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

//                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            BufferedOutputStream bw = new BufferedOutputStream( os );
            //向服务器端发送一条消息
//            String input = "000100000006FF0100640004";
            String input = instruct;
            byte[] byteInput = hexStr2bytes( input );
            logger.info("hex string： ", bytesToHexString(byteInput));

            bw.write( byteInput );
            bw.flush();

            //读取服务器返回的消息
//                BufferedReader br = new BufferedReader(new InputStreamReader(is));
//                String mess = br.readLine();

            BufferedInputStream bis = new BufferedInputStream( is );
            byte[] bytes = new byte[10]; // 一次读取一个byte
            String ret = "";
            bis.read(bytes);
            ret += bytesToHexString(bytes) + " ";  //调用字节转化16进制字符串方法


            logger.info("服务器：{}",ret);
            return ret;
        } catch (UnknownHostException e) {
            logger.error("sendInstruct throws exception is {}", e.getMessage(),e);
            return null;
        } catch (IOException e) {
            logger.error("sendInstruct throws exception is {}", e.getMessage(),e);
            return null;
        }
    }

    public static byte[] hexStr2bytes(String hexStr) {

        if(hexStr.length()%2 != 0) {//长度为单数
            hexStr = "0" + hexStr;//前面补0
        }
        char[] chars = hexStr.toCharArray();
        int len = chars.length/2;
        byte[] bytes = new byte[len];
        for (int i = 0; i < len; i++) {
            int x = i*2;
            bytes[i] = (byte)Integer.parseInt(String.valueOf(new char[]{chars[x], chars[x+1]}), 16);
        }
        return bytes;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            stringBuilder.append("0x");

            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            if (i != src.length-1) {
                stringBuilder.append(",");

            }
        }
        return stringBuilder.toString();
    }
}
